package com.hhs.storage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hhs.storage.bean.*;
import com.hhs.storage.dao.AttachmentListDao;
import com.hhs.storage.service.AttachmentListPerUserRoleService;
import com.hhs.storage.service.AttachmentListService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhs.storage.service.BaseRoleService;
import com.hhs.storage.service.BaseUserService;
import com.hhs.storage.util.DateEasy;
import com.hhs.storage.util.FileUpload;
import com.hhs.storage.util.StringUtil;
import com.hhs.storage.util.SysUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hhs
 * @since 2023-03-03
 */
@Service
@Transactional
public class AttachmentListServiceImpl extends ServiceImpl<AttachmentListDao, AttachmentList> implements AttachmentListService {
    @Value("${upload.folderName}")
    private String folderName;
    @Resource
    private HttpServletRequest request;
    @Resource
    private HttpServletResponse response;
    @Resource
    private BaseUserService baseUserService;
    @Resource
    private AttachmentListPerUserRoleService attachmentListPerUserRoleService;
    @Resource
    private BaseRoleService baseRoleService;
    /**
     * 查询目标id所有附件
     *
     * @return
     */
    @Override
    public Map<String, Object> queryByTargetId(InputParam inputParam) {
        String targetId=inputParam.getTargetId();
        if (StringUtils.isEmpty(targetId)) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("rows", new ArrayList());
            map.put("total", 0);
            map.put("code", 0);
            return map;
        }
        QueryWrapper<AttachmentList> qw = new QueryWrapper<>();
        if(!"allatt".equals(targetId)){
            String[] targetIds = targetId.split("_");
            qw.in("target_id", targetIds);
            if(inputParam.getType()!=null){
                qw.eq("type",inputParam.getType());
            }
        }else{
            String loginUserId = SysUtil.getLoginUserId(request);
            if(!("2".equals(loginUserId)||"21".equals(loginUserId))){
                qw.eq("user_id",loginUserId);
            }
            qw.eq("type",inputParam.getType());
        }

        //加入其它分类的搜索
        if(!StringUtil.iszNull(inputParam.getIncludeIds())){
            String[] ids=inputParam.getIncludeIds().split(",");
            qw.in("user_id",ids);
        }
        if(!StringUtil.iszNull(inputParam.getStartTime())){
            qw.ge("create_time",new DateEasy(inputParam.getStartTime()).toYYYYhMMhDDhHHcMMcSS());
        }
        if(!StringUtil.iszNull(inputParam.getEndTime())){
            qw.le("create_time",new DateEasy(inputParam.getEndTime()).toYYYYhMMhDDhHHcMMcSS());
        }
        qw.orderByDesc("create_time");
        Page<AttachmentList> result=null;
        //资料管理
        if(inputParam.getType()!=null&&inputParam.getType().equals(6)){
            result=new Page();
            inputParam.setUserId(SysUtil.getLoginUserId(request));
            List<BaseRole> r = baseRoleService.getByUserId(SysUtil.getLoginUserId(request));
            List<String> roleIds=r.stream().map(item->item.getId()).collect(Collectors.toList());
            inputParam.setRoleIds(roleIds);
            List<AttachmentList> la= this.baseMapper.pageZlgl(inputParam);
            int total=this.baseMapper.getPageZlglTotal(inputParam);
            //加入权限对象
            for (AttachmentList att :
                    la) {
                QueryWrapper<AttachmentListPerUserRole> qwa=new QueryWrapper<>();
                qwa.eq("attachment_list_id",att.getId());
                List<AttachmentListPerUserRole> listattlpr = attachmentListPerUserRoleService.list(qwa);
                //形成Map对象
                Map<String,Object> map=new LinkedHashMap();
                for (AttachmentListPerUserRole cc :
                        listattlpr) {
                    String key="";
                    if(cc.getType()==0){
                        key=cc.getUserId()+"_"+cc.getType();
                    }else if(cc.getType()==1){
                        key=cc.getRoleId()+"_"+cc.getType();
                    }
                    PermissionItem pii=(PermissionItem) map.get(key);
                    if(pii==null){
                        pii=new PermissionItem();
                        if(cc.getType()==0){
                            pii.setId(cc.getUserId());
                            pii.setType(cc.getType());
                            BaseUser un=baseUserService.getById(pii.getId());
                            if(un!=null)
                            pii.setName(un.getName());
                        }else if(cc.getType()==1){
                            pii.setId(cc.getRoleId());
                            pii.setType(cc.getType());
                            BaseRole rr = baseRoleService.getById(pii.getId());
                            if(rr!=null)
                            pii.setName(rr.getName());
                        }
                        map.put(key,pii);
                    }
                    pii.getCheckList().add(cc.getPermission());
                }
                att.setPermissionData(new ArrayList(map.values()));
            }
            result.setRecords(la);
            result.setTotal(total);
        }else{
            result = this.page(new Page<AttachmentList>(
                    inputParam.getPage(),
                    inputParam.getSize()), qw);
        }

        List<AttachmentList> list=result.getRecords();
        //加一下所有者的名字以有权限
        for (AttachmentList at:
                list) {
            String userName="";
            BaseUser b=baseUserService.getById(at.getUserId());
            if(b!=null){
                userName=b.getName();
            }
            at.setUserName(userName);
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rows", list);
        map.put("total", result.getTotal());
        map.put("code", 1);
        return map;
    }

    /**
     * 上传目标项目文件
     *
     *
     * @param permission
     * @param targetId 目标id
     * @param type 目标类型 0 个人计划,1项目计划
     * @param file 文件
     * @return
     */
    @Override
    public Map<String, Object> addByTargetId(String permission, String targetId, Integer type, MultipartFile file) {
        if (SysUtil.TARGET_TYPE_MAP.get(type)==null){
            return ResponseInfo.error("错误的参数");
        }
        String originalFilename=file.getOriginalFilename();//原文件名
        String suffix=originalFilename.substring(originalFilename.lastIndexOf(".")+1).toLowerCase();//文件后缀
        String fileType=SysUtil.FILE_TYPE_MAP.get(suffix);//根据后缀获取文件类型
        if (fileType==null&&type!=6){
            return ResponseInfo.error("错误文件类型【图片、word、excel、ppt、pdf、txt】");
        }else{
            if(StringUtil.iszNull(fileType)){
                fileType="未知";
            }
            fileType=suffix;

        }
        String id=SysUtil.UUID();
        //上传文件
        String url=FileUpload.writeUploadAllFile(file,folderName,SysUtil.ATTACHMENT_LIST);
        if (url == null) {
            return ResponseInfo.error("文件上传失败");
        }
        url=StringUtil.replace(url,"\\","/");
        //上传基本信息到数据库中
        AttachmentList obj=new AttachmentList();
        obj.setId(id);//id
        obj.setTargetId(targetId);//目标id
        obj.setUserId(SysUtil.getLoginUserId(request));//上传者
        obj.setType(type);//目标id
        obj.setCreateTime(LocalDateTime.now());//上传时间
        obj.setName(originalFilename);
        obj.setFileType(fileType);
        obj.setUrl(url);
        this.save(obj);
        //permission保存
        //先删除
//        QueryWrapper<AttachmentListPerUserRole> qwal=new QueryWrapper<>();
//        qwal.eq("attachment_list_id",id);
//        attachmentListPerUserRoleService.remove(qwal);
        JSONObject map = (JSONObject)JSONObject.parse(permission);
        if(map!=null){
            List<JSONObject> pda=(List)map.get("permissionData");
            if(pda!=null)
            for (JSONObject item :
                    pda) {
                if (((Integer) item.get("type"))==0){//用户
                    List<Integer> checkList = (List) item.get("checkList");
                    if(checkList!=null){
                        for (Integer p :
                                checkList) {
                            AttachmentListPerUserRole a=new AttachmentListPerUserRole();
                            a.setUserId((String)item.get("id"));
                            a.setType(0);
                            a.setAttachmentListId(id);
                            a.setPermission(p);
                            attachmentListPerUserRoleService.save(a);
                        }
                        if(checkList.size()==0){
                            AttachmentListPerUserRole a=new AttachmentListPerUserRole();
                            a.setUserId((String)item.get("id"));
                            a.setType(0);
                            a.setAttachmentListId(id);
                            attachmentListPerUserRoleService.save(a);
                        }
                    }else{
                        AttachmentListPerUserRole a=new AttachmentListPerUserRole();
                        a.setUserId((String)item.get("id"));
                        a.setType(0);
                        a.setAttachmentListId(id);
                        attachmentListPerUserRoleService.save(a);
                    }
                }
                if (((Integer) item.get("type"))==1){//角色
                    List<Integer> checkList = (List) item.get("checkList");
                    if(checkList!=null){
                        for (Integer p :
                                checkList) {
                            AttachmentListPerUserRole a=new AttachmentListPerUserRole();
                            a.setRoleId((String)item.get("id"));
                            a.setType(1);
                            a.setAttachmentListId(id);
                            a.setPermission(p);
                            attachmentListPerUserRoleService.save(a);
                        }
                        if(checkList.size()==0){
                            AttachmentListPerUserRole a=new AttachmentListPerUserRole();
                            a.setRoleId((String)item.get("id"));
                            a.setType(1);
                            a.setAttachmentListId(id);
                            attachmentListPerUserRoleService.save(a);
                        }
                    }else{
                        AttachmentListPerUserRole a=new AttachmentListPerUserRole();
                        a.setRoleId((String)item.get("id"));
                        a.setType(1);
                        a.setAttachmentListId(id);
                        attachmentListPerUserRoleService.save(a);
                    }
                }
            }
        }
        return ResponseInfo.success(obj);
    }

    /**
     * 删除文件
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> delete(String id) {
        AttachmentList obj=this.getById(id);
        FileUpload.deleteFile(folderName,obj.getUrl());//不删除文件
        this.removeById(id);
        QueryWrapper<AttachmentListPerUserRole> qwal=new QueryWrapper<>();
        qwal.eq("attachment_list_id",id);
        attachmentListPerUserRoleService.remove(qwal);
        return ResponseInfo.success();
    }

    /**
     * 下载文件
     * @param inputParam
     * @return
     */
    @Override
    public Map<String, Object> downLoad(InputParam inputParam) throws IOException {
        AttachmentList obj=new AttachmentList();
        if(!StringUtil.iszNull(inputParam.getId())){
            obj=this.getById(inputParam.getId());
        }
        if(!StringUtil.iszNull(inputParam.getPath())){
            QueryWrapper qw=new QueryWrapper();
            qw.eq("url",inputParam.getPath());
            try {
                obj=this.getOne(qw);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        //把服务器中文件读取到内存中
        FileInputStream fis=null;
        ServletOutputStream os=null;
        try{
            File f=new File(folderName,obj.getUrl());
            fis = new FileInputStream(f);
            //设置下载的类型
            response.setHeader("content-disposition","attachment;fileName="+ URLEncoder.encode(obj.getName(),"UTF-8"));
            response.addHeader("Content-Length", "" + f.length());
            response.setContentType("application/octet-stream");
            //获取输出流
            os = response.getOutputStream();
            //复制
            IOUtils.copy(fis,os);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(fis!=null){
                //关闭资源
                fis.close();
            }
            if(os!=null){
                os.close();
            }
        }

        return new HashMap<>();
    }

    /**
     * 删除目标项目文件
     *
     * @param targetId
     * @return
     */
    @Override
    public Map<String, Object> deleteByTargetId(String targetId) {
        QueryWrapper<AttachmentList> qw = new QueryWrapper<>();
        qw.eq("target_id", targetId);
        List<AttachmentList> list=this.list(qw);
        for (int i = 0; i <list.size() ; i++) {
            this.delete(list.get(i).getId());
        }
        return ResponseInfo.success();
    }

    @Override
    public Map<String, Object> copyOrCut(InputParam inputParam) {
        if(StringUtil.iszNull(inputParam.getIncludeIds())){
            return ResponseInfo.error("参数错误");
        }
        String[] idss=inputParam.getIncludeIds().split(",");
        for (String id :
                idss) {
            String[] idd = id.split("_");
            String idid=idd[0];
            String idop=idd[1];
            AttachmentList iditem = this.getById(idid);
            if("1".equals(idop)){
                //先删除
                this.removeById(idid);
                iditem.setId(null);
                iditem.setTargetId(inputParam.getTargetId());
                iditem.setUserId(SysUtil.getLoginUserId(request));
                this.save(iditem);
            }else if("0".equals(idop)){
                iditem.setId(null);
                iditem.setTargetId(inputParam.getTargetId());
                iditem.setUserId(SysUtil.getLoginUserId(request));
                this.save(iditem);
            }
        }
        return ResponseInfo.success();
    }

    @Override
    public Map<String, Object> addPermByTargetId(String targetId, List<PermissionItem> permissionData) {
        QueryWrapper<AttachmentListPerUserRole> qw=new QueryWrapper<>();
        qw.eq("attachment_list_id",targetId);
        attachmentListPerUserRoleService.remove(qw);
        for (PermissionItem pii :
                permissionData) {
            if(pii.getCheckList().size()==0){
                AttachmentListPerUserRole att = new AttachmentListPerUserRole();
                att.setAttachmentListId(targetId);
                att.setType(pii.getType());
                if(pii.getType()==0){
                    att.setUserId(pii.getId());
                }else if(pii.getType()==1){
                    att.setRoleId(pii.getId());
                }
                attachmentListPerUserRoleService.save(att);
            }
            for (Integer p :
                    pii.getCheckList()) {
                AttachmentListPerUserRole att = new AttachmentListPerUserRole();
                att.setAttachmentListId(targetId);
                att.setType(pii.getType());
                if(pii.getType()==0){
                    att.setUserId(pii.getId());
                }else if(pii.getType()==1){
                    att.setRoleId(pii.getId());
                }
                att.setPermission(p);
                attachmentListPerUserRoleService.save(att);
            }
        }
        return ResponseInfo.success(null);
    }

    @Override
    public Map<String, Object> setAvator(String url) {
        String loginUserId = SysUtil.getLoginUserId(request);
        BaseUser byId = baseUserService.getById(loginUserId);
        byId.setPhotoUrl(url);
        baseUserService.updateById(byId);
        return ResponseInfo.success();
    }
}
